package com.phunware.swipeToDismiss;

import java.util.ArrayList;
import java.util.List;

import android.app.Dialog;
import android.content.DialogInterface;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;

import com.phunware.swipeToDismiss.interfaces.ViewBinder;
import com.phunware.swipeToDismiss.pager.SwipingPagerAdapter;

public class SwipeToDismissAdapter<T> extends BaseAdapter {

	private final List<T> mObjects;
	private final ViewBinder<T> mBinder;
	private Dialog mDialog;
	private OnItemDismissListener mDismissListener;
	private OnItemCreateDialogListener mDialogListener;

	public SwipeToDismissAdapter(List<T> objects, ViewBinder<T> binder) {
		mObjects = objects;
		mBinder = binder;
	}
	
	public SwipeToDismissAdapter(ArrayAdapter<T> adapter) {
		mObjects = new ArrayList<T>();
		for (int i = 0; i < adapter.getCount(); i++) {
			mObjects.add(adapter.getItem(i));
		}
		mBinder = new AdapterWrapperBinder<T>(adapter);
	}

	public void setConfirmationDialog(Dialog dialog) {
		mDialog = dialog;
	}

	public void setOnItemDismissListener(OnItemDismissListener listener) {
		mDismissListener = listener;
	}

	public void setOnItemCreateDialogListener(
			OnItemCreateDialogListener listener) {
		mDialogListener = listener;
	}

	@Override
	public int getCount() {
		return mObjects.size();
	}

	@Override
	public T getItem(int position) {
		return mObjects.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@SuppressWarnings("unchecked")
	@Override
	public View getView(final int position, View convertView,
			final ViewGroup parent) {
		if (null == convertView) {
			convertView = LayoutInflater.from(parent.getContext()).inflate(
					R.layout.swipe_to_dismiss_frame, parent, false);
			ViewHolder<T> holder = new ViewHolder<T>();
			ViewPager pager = (ViewPager) convertView.findViewById(R.id.pager);
			pager.setAdapter(new SwipingPagerAdapter<T>(mBinder));
			holder.pager = pager;
			convertView.setTag(holder);
		}
		final ViewHolder<T> holder = (ViewHolder<T>) convertView.getTag();

		holder.item = getItem(position);

		holder.pager.setOnPageChangeListener(null);
		holder.pager.setCurrentItem(1, false);
		holder.pager.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int pos) {
				if (pos != 1) {
					if (mDialogListener != null) {
						mDialog = mDialogListener
								.onItemCreateDialog(holder.item);
					}
					if (mDialog != null) {
						DialogHandler listener = new DialogHandler(holder);
						mDialog.setOnCancelListener(listener);
						mDialog.setOnDismissListener(listener);
						mDialog.show();
					} else {
						removeItem(holder.item);
					}
				}
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
			}

			@Override
			public void onPageScrollStateChanged(int state) {
				if (ViewPager.SCROLL_STATE_DRAGGING == state) {
					parent.requestDisallowInterceptTouchEvent(true);
				}
			}
		});

		((SwipingPagerAdapter<T>) holder.pager.getAdapter())
				.setItem(getItem(position));

		// Set pager to be the height of its child view
		View child = ((SwipingPagerAdapter<T>) holder.pager.getAdapter())
				.getMainView(holder.pager);
		child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
		LayoutParams params = convertView.getLayoutParams();
		params.height = child.getMeasuredHeight();
		convertView.setLayoutParams(params);

		// make items clickable
		// ((ListView) parent).setItemsCanFocus(true);

		/*holder.pager.setClickable(true);
		holder.pager.setFocusable(true);
		holder.pager.setBackgroundDrawable(((ListView) parent).getSelector());*/

		return convertView;
	}

	private static class ViewHolder<E> {
		public ViewPager pager;
		public E item;
	}

	public void removeItem(int position) {
		if (mDismissListener != null) {
			mDismissListener.onItemDismiss(getItem(position));
		}
		mObjects.remove(position);
		notifyDataSetChanged();
	}

	public void removeItem(T object) {
		if (mDismissListener != null) {
			mDismissListener.onItemDismiss(object);
		}
		mObjects.remove(object);
		notifyDataSetChanged();
	}

	private class DialogHandler implements DialogInterface.OnCancelListener,
			DialogInterface.OnDismissListener {

		private ViewHolder<T> mHolder;

		public DialogHandler(ViewHolder<T> holder) {
			mHolder = holder;
		}

		@Override
		public void onDismiss(DialogInterface dialog) {
			if (mHolder != null) {
				removeItem(mHolder.item);
			}
		}

		@Override
		public void onCancel(DialogInterface dialog) {
			if (mHolder != null) {
				mHolder.pager.setCurrentItem(1);
				mHolder = null;
			}
		}

	}

	public static interface OnItemDismissListener {
		public void onItemDismiss(Object item);
	}

	public static interface OnItemCreateDialogListener {
		public Dialog onItemCreateDialog(Object item);
	}

	protected static class AdapterWrapperBinder<T> implements ViewBinder<T> {

		private final ArrayAdapter<T> mAdapter;

		public AdapterWrapperBinder(ArrayAdapter<T> adapter) {
			mAdapter = adapter;
		}

		@Override
		public View bind(T object, View convertView, ViewGroup parent) {
			return mAdapter.getView(mAdapter.getPosition(object), convertView,
					parent);
		}

	}
}
